package org.tinygroup.tinytest;

import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.test.context.ContextLoader;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.SmartContextLoader;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.DefaultTestContext;
import org.springframework.test.context.support.DefaultTestContextBootstrapper;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.springutil.ExtendsSpringBeanContainer;
import org.tinygroup.tinyrunner.Runner;

/**
 * 
 * @author renhui
 *
 */
public class TinyDefaultTestContextBootstrapper extends
		DefaultTestContextBootstrapper {

	private final Log logger = LogFactory.getLog(getClass());
	
	public TestContext buildTestContext() {
		return new DefaultTestContext(getBootstrapContext().getTestClass(),
				buildTinyMergedContextConfiguration(),
				getCacheAwareContextLoaderDelegate());
	}

	protected MergedContextConfiguration buildTinyMergedContextConfiguration() {
		MergedContextConfiguration mergedContextConfiguration = super
				.buildMergedContextConfiguration();
		// 获取contextLoader
		ContextLoader contextLoader = mergedContextConfiguration
				.getContextLoader();
		if (contextLoader == null) {
			contextLoader = BeanUtils.instantiateClass(
					getDefaultContextLoaderClass(getBootstrapContext()
							.getTestClass()), ContextLoader.class);
		}
		ContextLoader tinyContextLoader = new TinyDelegatingSmartContextLoader(
				(SmartContextLoader) contextLoader);
		if (logger.isDebugEnabled()) {
			logger.debug(String
					.format("TinyWebTestContextBootstrapper really ContextLoader: [%s]",
							tinyContextLoader.getClass().getName()));
		}
		// 启动tiny框架
		ExtendsSpringBeanContainer beanContainer = (ExtendsSpringBeanContainer) BeanContainerFactory
				.getBeanContainer(getClass().getClassLoader());
		if(beanContainer==null){
			BeanContainerFactory.initBeanContainer(ExtendsSpringBeanContainer.class
    				.getName());
    		beanContainer = (ExtendsSpringBeanContainer) BeanContainerFactory
    				.getBeanContainer(getClass().getClassLoader());
    		FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext();
    		beanContainer.setApplicationContext(context);
    		Runner.init(ExtendsSpringBeanContainer.class, null,
    				new ArrayList<String>());
		}
		ApplicationContext context=beanContainer.getBeanContainerPrototype();
		TinyCacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = (TinyCacheAwareContextLoaderDelegate) getCacheAwareContextLoaderDelegate();
		MergedContextConfiguration newParentMergedContextConfiguration = new MergedContextConfiguration(
				null, null, null, null, tinyContextLoader);
		cacheAwareContextLoaderDelegate.getPublicContextCache().put(
				newParentMergedContextConfiguration, context);
		MergedContextConfiguration newMergedContextConfiguration = new TinyMergedContextConfiguration(
				tinyContextLoader, cacheAwareContextLoaderDelegate,
				mergedContextConfiguration, newParentMergedContextConfiguration);
		if (logger.isDebugEnabled()) {
			logger.debug(String
					.format("TinyWebTestContextBootstrapper build MergedContextConfiguration: [%s]",
							newMergedContextConfiguration.getClass().getName()));
		}
		return newMergedContextConfiguration;
	}

}
